/**
  ******************************************************************************
  * @file    rs485n1.c
  * @brief   This file provides code for the configuration
  *          of all used GPIO pins.
  ******************************************************************************
  * @attention
  * 对于此款遥控器,长按最多产生108个.
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "bsp.h"
#include "tskcfg.h"
#include "irkey.h"
#include <string.h>

static IrKey_WaveStru irkey_wave_isr;

void irkey_init(void)
{
  LL_TIM_InitTypeDef TIM_InitStruct = {0};
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM12);
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
  
  GPIO_InitStruct.Pin = LL_GPIO_PIN_14;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_9;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  NVIC_SetPriority(TIM8_BRK_TIM12_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),IRKEY_TIMER_IRQ_PRIORITY, 0));
  NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn);
  
  /* 25分频  粒度0.25us 最长周期为16.384ms 
     100分频 粒度1us    最长周期为65.536ms
     200分频 粒度2us    最长周期为131.072ms */
  TIM_InitStruct.Prescaler = 100-1;
  TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
  TIM_InitStruct.Autoreload = 9000;  /* 超过9ms则判断是下一个按键 */
  TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
  LL_TIM_Init(TIM12, &TIM_InitStruct);
  
  LL_TIM_DisableARRPreload(TIM12);
  
  LL_TIM_SetClockSource(TIM12, LL_TIM_CLOCKSOURCE_INTERNAL);
  LL_TIM_SetTriggerInput(TIM12, LL_TIM_TS_TI1FP1);
  LL_TIM_SetSlaveMode(TIM12, LL_TIM_SLAVEMODE_RESET);
  
  LL_TIM_IC_SetActiveInput(TIM12, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI);
  LL_TIM_IC_SetActiveInput(TIM12, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI);
  
  LL_TIM_IC_SetPolarity(TIM12, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_FALLING);
  LL_TIM_IC_SetPolarity(TIM12, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING);
  
  LL_TIM_IC_SetPrescaler(TIM12, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1);
  LL_TIM_IC_SetPrescaler(TIM12, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
  
  LL_TIM_IC_SetFilter(TIM12, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV32_N8);
  LL_TIM_IC_SetFilter(TIM12, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV32_N8);
  
  LL_TIM_SetUpdateSource(TIM12, LL_TIM_UPDATESOURCE_COUNTER);
  
  LL_TIM_EnableIT_UPDATE(TIM12);
  LL_TIM_EnableIT_CC1(TIM12);
  LL_TIM_DisableIT_CC2(TIM12);
  LL_TIM_DisableIT_TRIG(TIM12);
  LL_TIM_DisableDMAReq_TRIG(TIM12);
  
  LL_TIM_CC_EnableChannel(TIM12, LL_TIM_CHANNEL_CH1);
  LL_TIM_CC_EnableChannel(TIM12, LL_TIM_CHANNEL_CH2);
  
  LL_TIM_DisableCounter(TIM12);
//  LL_TIM_EnableCounter(TIM12);
}

void TIM8_BRK_TIM12_IRQHandler(void)
{
  if(LL_TIM_IsActiveFlag_UPDATE(TIM12) == 1)
  {
    LL_TIM_ClearFlag_UPDATE(TIM12);

    LL_TIM_DisableCounter(TIM12);

    if(irkey_wave_isr.cnt >= IRKEY_WAVE_EFFECTIVE_LEN)
    {
      xQueueSendFromISR(irkey_wave_qhd, &irkey_wave_isr, NULL);
    }

    WRITE_REG(TIM12->CCR1, 0);
    WRITE_REG(TIM12->CCR2, 0);
    irkey_wave_isr.cnt = 0;
  }

  if(LL_TIM_IsActiveFlag_CC1(TIM12) == 1)
  {
    LL_TIM_ClearFlag_CC1(TIM12);
    
    LL_TIM_EnableCounter(TIM12);

    if(irkey_wave_isr.cnt < IRKEY_WAVE_BUF_MAX)
    {
      irkey_wave_isr.ccr1[irkey_wave_isr.cnt] = LL_TIM_IC_GetCaptureCH1(TIM12);
      irkey_wave_isr.ccr2[irkey_wave_isr.cnt] = LL_TIM_IC_GetCaptureCH2(TIM12);
      irkey_wave_isr.cnt++;
    }
    else
    {
      xQueueSendFromISR(irkey_wave_qhd, &irkey_wave_isr, NULL);
      irkey_wave_isr.cnt = 0;
    }
  }
  
  if(LL_TIM_IsActiveFlag_CC2(TIM12) == 1)
  {
    LL_TIM_ClearFlag_CC2(TIM12);

    LL_TIM_EnableCounter(TIM12);
  }
}
